Skip to content

Change the desugaring of assert! for better error output #122661

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

estebank
Copy link
Contributor

@estebank estebank commented Mar 17, 2024

In the desugaring of assert!, we now expand to a match expression instead of if !cond {..}.

The span of incorrect conditions will point only at the expression, and not the whole assert! invocation.

error[E0308]: mismatched types
  --> $DIR/issue-14091.rs:2:13
   |
LL |     assert!(1,1);
   |             ^ expected `bool`, found integer

We no longer mention the expression needing to implement the Not trait.

error[E0308]: mismatched types
  --> $DIR/issue-14091-2.rs:15:13
   |
LL |     assert!(x, x);
   |             ^ expected `bool`, found `BytePos`

Now assert!(val) desugars to:

match val {
    true => {},
    _ => $crate::panic::panic_2021!(),
}

Fix #122159.

@rustbot
Copy link
Collaborator

rustbot commented Mar 17, 2024

r? @pnkfelix

rustbot has assigned @pnkfelix.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Mar 17, 2024
@rustbot
Copy link
Collaborator

rustbot commented Mar 17, 2024

rust-analyzer is developed in its own repository. If possible, consider making this change to rust-lang/rust-analyzer instead.

cc @rust-lang/rust-analyzer

The Miri subtree was changed

cc @rust-lang/miri

assert!((() <= ()));
assert!((!(() > ())));
assert!((() >= ()));
assert!(!(() != ()));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these are because now the unnecessary parentheses lint (correctly) triggers on assert!((expr)).

Comment on lines 1 to 14
error[E0600]: cannot apply unary operator `!` to type `BytePos`
--> $DIR/issue-14091-2.rs:15:5
error[E0308]: mismatched types
--> $DIR/issue-14091-2.rs:15:13
|
LL | assert!(x, x);
| ^^^^^^^^^^^^^ cannot apply unary operator `!`
|
note: an implementation of `Not` might be missing for `BytePos`
--> $DIR/issue-14091-2.rs:6:1
|
LL | pub struct BytePos(pub u32);
| ^^^^^^^^^^^^^^^^^^ must implement `Not`
note: the trait `Not` must be implemented
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
= note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the best example of how this is an improvement.

@rust-log-analyzer

This comment has been minimized.

@estebank estebank force-pushed the assert-macro-span branch from ead1593 to eb411c1 Compare March 17, 2024 21:27
@rust-log-analyzer

This comment has been minimized.

@estebank
Copy link
Contributor Author

Sigh, clippy shows at least one test where a suggestion causes there to be a condition that isn't a bool but rather a type where Not returns a bool. We can easily continue supporting that by making the desugaring !!cond, but would rather not do that. This happens when it suggest changing assert_eq!(non_bool, true), ending up as assert!(non_bool), which doesn't work with this change .

@rustbot

This comment was marked as resolved.

@rust-log-analyzer

This comment has been minimized.

@pnkfelix
Copy link
Member

Isn't this technically a breaking change for e.g. (playground):

struct Booly(i32);

impl std::ops::Not for Booly {
    type Output = bool;
    fn not(self) -> Self::Output {
        self.0 == 0
    }
}

fn main() {
    assert!(Booly(1), "booly booly!")
}

@pnkfelix
Copy link
Member

At the very least, we might need to tie such a change to an edition.

I am not certain whether this decision would be a T-lang matter or a T-libs-api one. I'll nominate for T-lang for now.

(Namely: The question is whether we can start enforcing a rule that the first expression to assert! must be of bool type, which is how the macro is documented, but its current behavior is a little bit more general, as demonstrated in my prior comment)

@rustbot label +I-lang-nominated

@rustbot rustbot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Mar 18, 2024
@estebank
Copy link
Contributor Author

estebank commented Mar 18, 2024

@pnkfelix we can keep the current (undocumented) behavior by making the desugaring be

{
    let x: bool = !!condition;
    x
}

instead of what this PR does:

{
    let x: bool = condition;
    x
}

I believe that would still cause errors to complain about Not not being implemented, instead of the more straightforward type error, albeit with a better span. I don't particularly like the idea of keeping the current emergent behavior if there aren't people exploiting it in crates.io.

Edit: an option would be to have an internal marker trait:

use std::ops::Not;
trait CanAssert {}
impl<T: Not<Output = bool>> CanAssert for T {}

fn main() {
    let _ = Box::new(true) as Box<dyn CanAssert>;
    let _ = Box::new(42) as Box<dyn CanAssert>;
}
error[E0271]: type mismatch resolving `<i32 as Not>::Output == bool`
 --> src/main.rs:7:13
  |
7 |     let _ = Box::new(42) as Box<dyn CanAssert>;
  |             ^^^^^^^^^^^^ expected `bool`, found `i32`
  |
note: required for `i32` to implement `CanAssert`
 --> src/main.rs:3:29
  |
3 | impl<T: Not<Output = bool>> CanAssert for T {}
  |             -------------   ^^^^^^^^^     ^
  |             |
  |             unsatisfied trait bound introduced here
  = note: required for the cast from `Box<i32>` to `Box<dyn CanAssert>`

@pnkfelix
Copy link
Member

pnkfelix commented Mar 18, 2024

@estebank what about making the expansion edition-dependent? Is there precedent for that?

Then, editions >= 2024 would expand to what you have proposed in the code of this PR, and editions < 2024 could expand to the !!condition variant form that you have discussed in the comments?

@pnkfelix
Copy link
Member

what about making the expansion edition-dependent? Is there precedent for that?

(to answer my own question, panic! is one obvious precedent here. So it seems like making it edition-dependent would be one acceptable path; no opinion yet as to which is best...)

@estebank estebank force-pushed the assert-macro-span branch from c8185ea to 07a5b21 Compare March 18, 2024 23:59
@rustbot
Copy link
Collaborator

rustbot commented Mar 19, 2024

Some changes occurred in coverage tests.

cc @Zalathar

@estebank
Copy link
Contributor Author

I tried the marker trait approach for <=2021, and it kind of worked, but the diagnostics were actually worse than just doing { let x: bool = !!$expr; x }, which accounts for pretty much everything we currently support, but with better spans and better errors (if typeof($expr) implements <Not<Output = NotBool>, we now produce an appropriate E0308 type error).

@rust-log-analyzer

This comment has been minimized.

@compiler-errors
Copy link
Member

Since I don't think it's been acknowledged above, for the record, this breaks the following code:

fn hello(x: &bool) {
  assert!(x);
}

Because &bool: Not<Output = bool>.

@estebank
Copy link
Contributor Author

@compiler-errors that is indeed the case for 2024 onwards, not for previous editions.

@pnkfelix
Copy link
Member

pnkfelix commented Mar 20, 2024

@compiler-errors that is indeed the case for 2024 onwards, not for previous editions.

I think the critical point is whether an edition-dependent expansion is worth breaking that case (of assert!(x) where x: &bool), or if we should do a non-breaking non-edition-dependent expansion using the let x: bool = !!$expr trick across the board...


Update: I don't know whether it is worth going through this exercise explicitly, but there is a design space here. E.g. one set of options is:

  1. (stable Rust behavior): in all editions, support arbitrary impl Not<Output=bool> for first parameter to assert!;
  2. in edition >= 2024, support just Deref<Target=bool> for first parameter to assert! (e.g. by expanding to let x: &bool = &$expr;), or
  3. (this PR): in edition >= 2024, support just bool for first parameter to assert!.

(And then there's variations thereof about how to handle editions < 2024, but that's a separate debate IMO.)

@pnkfelix
Copy link
Member

pnkfelix commented Mar 22, 2024

(this is waiting for a decision from T-lang and/or T-libs regarding what interface we want to commit to for assert!)

@rustbot label: +S-waiting-on-team -S-waiting-on-review

@craterbot
Copy link
Collaborator

🚨 Error: missing start toolchain

🆘 If you have any trouble with Crater please ask in t-infra on Zulip
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@estebank
Copy link
Contributor Author

@bors try

bors added a commit that referenced this pull request Jul 18, 2025
Change the desugaring of `assert!` for better error output

In the desugaring of `assert!`, we now expand to a `match` expression instead of `if !cond {..}`.

The span of incorrect conditions will point only at the expression, and not the whole `assert!` invocation.

```
error[E0308]: mismatched types
  --> $DIR/issue-14091.rs:2:13
   |
LL |     assert!(1,1);
   |             ^ expected `bool`, found integer
```

We no longer mention the expression needing to implement the `Not` trait.

```
error[E0308]: mismatched types
  --> $DIR/issue-14091-2.rs:15:13
   |
LL |     assert!(x, x);
   |             ^ expected `bool`, found `BytePos`
```

Now `assert!(val)` desugars to:

```rust
match val {
    true => {},
    _ => $crate::panic::panic_2021!(),
}
```

Fix #122159.
@bors
Copy link
Collaborator

bors commented Jul 18, 2025

⌛ Trying commit b3ffb52 with merge a2a6e87...

@bors
Copy link
Collaborator

bors commented Jul 18, 2025

☀️ Try build successful - checks-actions
Build commit: a2a6e87 (a2a6e871b05c7b8ecc9a3c8a20db1f39e995e399)

@estebank
Copy link
Contributor Author

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-122661 created and queued.
🤖 Automatically detected try build a2a6e87
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 20, 2025
@craterbot
Copy link
Collaborator

🚧 Experiment pr-122661 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-122661 is completed!
📊 32 regressed and 10 fixed (668001 total)
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Jul 24, 2025
@traviscross
Copy link
Contributor

traviscross commented Jul 24, 2025

It's interesting how this ends up interacting, on older editions, with things we improved in Rust 2024. Most (but not all) of the regressions match this pattern:

use core::cell::RefCell;

fn f1() {
    let x = RefCell::new([0u8]);
    if !x.borrow().is_empty() { //~ OK
        panic!()
    }
}

fn f2() {
    let x = RefCell::new([0u8]);
    match x.borrow().is_empty() {
        //[2021]~^ ERROR does not live long enough
        //[2024]~^ OK
        false => panic!(),
        _ => (),
    }
}

Both versions work in Rust 2024, but the latter fails in earlier editions due to the rule about temporaries in tail expressions. The f1 version works because if drops the temporaries in its condition before entering either branch, but match doesn't do this for its scrutinee, so the scopes of these temporaries extend beyond the match itself and therefore interact with the old-edition tail expression rule.

@estebank
Copy link
Contributor Author

There are at least two potential sources of regressions:

Lifetimes:

[INFO] [stdout] error[E0597]: `data` does not live long enough
[INFO] [stdout]    --> src/controllers/servitor/authorization.rs:134:11
[INFO] [stdout]     |
[INFO] [stdout] 124 |         let data = mock_data(None);
[INFO] [stdout]     |             ---- binding `data` declared here
[INFO] [stdout] ...
[INFO] [stdout] 134 |         assert!(data.read().await.servitor.is_empty())
[INFO] [stdout]     |                 ^^^^-------------
[INFO] [stdout]     |                 |
[INFO] [stdout]     |                 borrowed value does not live long enough
[INFO] [stdout]     |                 a temporary with access to the borrow is created here ...
[INFO] [stdout] 135 |     }
[INFO] [stdout]     |     -
[INFO] [stdout]     |     |
[INFO] [stdout]     |     `data` dropped here while still borrowed
[INFO] [stdout]     |     ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `tokio::sync::RwLockReadGuard`
[INFO] [stdout]     |
[INFO] [stdout] help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
[INFO] [stdout]     |
[INFO] [stdout] 134 |         assert!(data.read().await.servitor.is_empty());
[INFO] [stdout]     |                                                       +

I think I just need to change the desugaring to be for a statement of a match instead of a match expression.

Inference:

[INFO] [stdout] error[E0282]: type annotations needed
[INFO] [stdout]   --> java_runtime/tests/classes/java/util/jar/test_jar_file.rs:63:18
[INFO] [stdout]    |
[INFO] [stdout] 63 |     assert!(!jvm.invoke_virtual(&entries, "hasMoreElements", "()Z", ()).await?);
[INFO] [stdout]    |                  ^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the method `invoke_virtual`
[INFO] [stdout]    |
[INFO] [stdout] help: consider specifying the generic arguments
[INFO] [stdout]    |
[INFO] [stdout] 63 |     assert!(!jvm.invoke_virtual::<(), U>(&entries, "hasMoreElements", "()Z", ()).await?);
[INFO] [stdout]    |                                +++++++++

I don't think there's anything we can do to avoid the inference regression, but thankfully only two crates have real code that triggers it.

@teor2345
Copy link
Contributor

teor2345 commented Jul 24, 2025

Most fixes are spurious, they seem to be in build tools.

There are a few (expected?) type ambiguity errors, and many more drop order errors.

Type ambiguity (2 crates)

cradle 0.2.2

[INFO] [stdout] error[E0282]: type annotations needed
[INFO] [stdout]    --> src/lib.rs:972:21
[INFO] [stdout]     |
[INFO] [stdout] 972 |             assert!(!run_output!("false"));
[INFO] [stdout]     |                     ^^^^^^^^^^^^^^^^^^^^^ cannot infer type

dlunch/jvm -> rust_java v0.0.1 (?)

[INFO] [stderr]     Checking rust_java v0.0.1 (/opt/rustwide/workdir)
[INFO] [stdout] error[E0282]: type annotations needed
[INFO] [stdout]   --> java_runtime/tests/classes/java/util/jar/test_jar_file.rs:63:18
[INFO] [stdout]    |
[INFO] [stdout] 63 |     assert!(!jvm.invoke_virtual(&entries, "hasMoreElements", "()Z", ()).await?);
[INFO] [stdout]    |                  ^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the method `invoke_virtual`
[INFO] [stdout]    |
[INFO] [stdout] help: consider specifying the generic arguments
[INFO] [stdout]    |
[INFO] [stdout] 63 |     assert!(!jvm.invoke_virtual::<(), U>(&entries, "hasMoreElements", "()Z", ()).await?);
[INFO] [stdout]    |                                +++++++++

Drop order (22 crates)

Most failures seem to be around drop order when the assert is not followed by a semicolon. Hyrum's law in action.

mutex lock drop order

syndicus 0.3.1

[INFO] [stderr]     Checking syndicus v0.3.1 (/opt/rustwide/workdir)
[INFO] [stdout] error[E0597]: `counter` does not live long enough
[INFO] [stdout]   --> src/scope.rs:79:18
[INFO] [stdout]    |
[INFO] [stdout] 65 |         let counter = scope::<_, ()>(|tasker| {
[INFO] [stdout]    |             ------- binding `counter` declared here
[INFO] [stdout] ...
[INFO] [stdout] 79 |         assert!(*counter.lock().await == task_load)
[INFO] [stdout]    |                  ^^^^^^^-------------
[INFO] [stdout]    |                  |
[INFO] [stdout]    |                  borrowed value does not live long enough
[INFO] [stdout]    |                  a temporary with access to the borrow is created here ...
[INFO] [stdout] 80 |     }
[INFO] [stdout]    |     -
[INFO] [stdout]    |     |
[INFO] [stdout]    |     `counter` dropped here while still borrowed
[INFO] [stdout]    |     ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `tokio::sync::MutexGuard`
[INFO] [stdout]    |
[INFO] [stdout] help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
[INFO] [stdout]    |
[INFO] [stdout] 79 |         assert!(*counter.lock().await == task_load);

statsig-rust 0.6.2-beta.2507190239 in tests

Similar to the lock above:

[INFO] [stderr]     Checking statsig-rust v0.6.2-beta.2507190239 (/opt/rustwide/workdir)
…
[INFO] [stdout] error[E0597]: `obs_client` does not live long enough
[INFO] [stdout]    --> tests/event_logger_flush_tests.rs:346:13
…
[INFO] [stdout] 346 |     assert!(obs_client.error_calls.lock().unwrap().is_empty())

saptest 0.5.0 in tests

Similar to the lock above:

[INFO] [stderr]     Checking saptest v0.5.0 (/opt/rustwide/workdir)
[INFO] [stdout]    --> src/lib/tests/test_hard_mode_toy_t1.rs:164:13
…
[INFO] [stdout] error[E0597]: `pets` does not live long enough
[INFO] [stdout] 164 |     assert!(pets[2].read().unwrap().item.is_none())
…
[INFO] [stdout] error[E0597]: `pets` does not live long enough
[INFO] [stdout]    --> src/lib/tests/test_hard_mode_toy_t1.rs:192:13
[INFO] [stdout]     |
…
[INFO] [stdout] 192 |     assert!(pets[2].read().unwrap().item.is_none())

Also:

  • reqwest-conditional-middleware 0.4.0 in tests:
    • src/lib.rs:161
    • src/lib.rs:180
  • happylock 0.5.0 in tests (?)
    • src/collection/boxed.rs, many errors
  • rainshowerLabs/blutgang
  • Angelin01/gjallarbot

Other drop order

scylla-cql 1.3.0 -> criterion v0.6.0 (?)

Iterator drop order

[INFO] [stderr]     Checking criterion v0.6.0
[INFO] [stdout] error[E0597]: `values` does not live long enough
[INFO] [stdout]    --> src/serialize/row_tests.rs:564:13
[INFO] [stdout]     |
[INFO] [stdout] 551 |       let mut values = SerializedValues::new();
[INFO] [stdout]     |           ---------- binding `values` declared here
[INFO] [stdout] ...
[INFO] [stdout] 564 |       assert!(values
[INFO] [stdout]     |               -^^^^^
[INFO] [stdout]     |               |
[INFO] [stdout]     |  _____________borrowed value does not live long enough
[INFO] [stdout]     | |
[INFO] [stdout] 565 | |         .iter()
[INFO] [stdout]     | |_______________- a temporary with access to the borrow is created here ...
[INFO] [stdout] 566 |           .all(|v| v == RawValue::Value(&[0, 0, 0, 0, 0x07, 0x5b, 0xcd, 0x15])))
[INFO] [stdout] 567 |   }
[INFO] [stdout]     |   -
[INFO] [stdout]     |   |
[INFO] [stdout]     |   `values` dropped here while still borrowed
[INFO] [stdout]     |   ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `impl Iterator<Item = RawValue<'_>>`
[INFO] [stdout]     |
[INFO] [stdout] help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
[INFO] [stdout]     |
[INFO] [stdout] 566 |         .all(|v| v == RawValue::Value(&[0, 0, 0, 0, 0x07, 0x5b, 0xcd, 0x15])));
[INFO] [stdout]     |  

Also:

  • orc 0.0.1 in tests: heap allocator (?) drop order
    • src/lib.rs:268
  • laurel 0.7.2 -> toml v0.8.20: RefCell
    • src/coalesce.rs:1863
  • anyflux 0.1.0: Rc
    • src/context.rs:152
  • analyse-json 0.6.1, cbrown1234/analyse-json in tests (?): Rc
    • src/json/ndjson.rs, many errors
  • mukuact/simCAN: RefCell
  • l0s/rlox: Rc
  • kimond/rust_cmustify: RefCell
  • hi-rustin/rq: Iterator
  • gpabois/jarnac: RefPage
  • dlunch/Renderer: Iterator
  • babarai45/crux_fram: Iterator
  • astahhu/calendar-join: impl Deref
  • JohnMitchell04/toy-langauge: Ref, Result<Module<'_>, _>
  • Barandis/rust-c64: Ref

In the desugaring of `assert!`, we now expand to a `match` expression
instead of `if !cond {..}`.

The span of incorrect conditions will point only at the expression, and not
the whole `assert!` invocation.

```
error[E0308]: mismatched types
  --> $DIR/issue-14091.rs:2:13
   |
LL |     assert!(1,1);
   |             ^ expected `bool`, found integer
```

We no longer mention the expression needing to implement the `Not` trait.

```
error[E0308]: mismatched types
  --> $DIR/issue-14091-2.rs:15:13
   |
LL |     assert!(x, x);
   |             ^ expected `bool`, found `BytePos`
```

`assert!(val)` now desugars to:

```rust
match val {
    true => {},
    _ => $crate::panic::panic_2021!(),
}
```

Fix rust-lang#122159.

We make some minor changes to some diagnostics to avoid span overlap on
type mismatch or inverted "expected"/"found" on type errors.

We remove some unnecessary parens from core, alloc and miri.
@estebank estebank force-pushed the assert-macro-span branch from b3ffb52 to 9120542 Compare July 25, 2025 00:47
@rustbot
Copy link
Collaborator

rustbot commented Jul 25, 2025

This PR modifies tests/ui/issues/. If this PR is adding new tests to tests/ui/issues/,
please refrain from doing so, and instead add it to more descriptive subdirectories.

@rustbot
Copy link
Collaborator

rustbot commented Jul 25, 2025

⚠️ Warning ⚠️

  • There are issue links (such as #123) in the commit messages of the following commits.
    Please move them to the PR description, to avoid spamming the issues with references to the commit, and so this bot can automatically canonicalize them to avoid issues with subtree.

@estebank
Copy link
Contributor Author

@bors try

@rust-bors
Copy link

rust-bors bot commented Jul 25, 2025

⌛ Trying commit 9120542 with merge b047d5f

To cancel the try build, run the command @bors try cancel.

rust-bors bot added a commit that referenced this pull request Jul 25, 2025
Change the desugaring of `assert!` for better error output
@traviscross
Copy link
Contributor

If someone has a minimization of those type inference regressions, probably we'll be interested to look at that.

@rust-bors
Copy link

rust-bors bot commented Jul 25, 2025

☀️ Try build successful (CI)
Build commit: b047d5f (b047d5f4496a7526d91d0dddea494c05853f2a7b, parent: b56aaec52bc0fa35591a872fb4aac81f606e265c)

@estebank
Copy link
Contributor Author

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-122661-1 created and queued.
🤖 Automatically detected try build b047d5f
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 25, 2025
@estebank
Copy link
Contributor Author

@traviscross I've been trying to replicate a case where inference fails under the new desugaring but the old doesn't, and I'm having trouble doing so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. S-waiting-on-crater Status: Waiting on a crater run to be completed. T-clippy Relevant to the Clippy team. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

inconsistent and confusing error message about first argument of assert!